
public class ZoomManager
{
    private static double ZoomFactor = 1.0;

    private static boolean ZoomFactorFixedUsed = false;
    private static double ZoomFactorCustomLast = ZoomFactor; // F6
    private final static double ZoomFactorFixedSmall = 0.01; // F5 (toggle)
    private final static double ZoomFactorFixedLarge = 1.00; // F5 (toggle)

    private static int DrawWidth = 0;
    private static int DrawHeight = 0;

    private static int ZoomShiftX = 0;
    private static int ZoomShiftY = 0;

    private static int DrawWidthMinusZoomShiftX = 0;
    private static int DrawHeightMinusZoomShiftY = 0;

    private static int ZoomShiftXDivZoomFactor = 0;
    private static int ZoomShiftYDivZoomFactor = 0;

    private static int DrawWidthMinusZoomShiftXDivZoomFactor = 0;
    private static int DrawHeightMinusZoomShiftYDivZoomFactor = 0;

    private static int NegZoomShiftXDivZoomFactor = 0;
    private static int NegZoomShiftYDivZoomFactor = 0;

    public static int GetDrawHeightMinusZoomShiftY()
    {
        return DrawHeightMinusZoomShiftY;
    }

    public static int GetDrawHeightMinusZoomShiftYDivZoomFactor()
    {
        return DrawHeightMinusZoomShiftYDivZoomFactor;
    }

    public static int GetDrawWidthMinusZoomShiftX()
    {
        return DrawWidthMinusZoomShiftX;
    }

    public static int GetDrawWidthMinusZoomShiftXDivZoomFactor()
    {
        return DrawWidthMinusZoomShiftXDivZoomFactor;
    }

    public static int GetNegZoomShiftXDivZoomFactor()
    {
        return NegZoomShiftXDivZoomFactor;
    }

    public static int GetNegZoomShiftYDivZoomFactor()
    {
        return NegZoomShiftYDivZoomFactor;
    }

    public static double GetZoomFactor()
    {
        return ZoomFactor;
    }

    public static double GetZoomFactorCustomLast()
    {
        return ZoomFactorCustomLast;
    }

    public static String GetZoomInfoText(double ZoomFactor)
    {
        String ZoomInfoText = "ZOOM [" + Math.min(100, (int) (ZoomFactor * 101.0)) + "%]"; // 10*1*.0 against rounding/FP errors (necessary, tested)

        return ZoomInfoText;
    }

    public static int GetZoomShiftX()
    {
        return ZoomShiftX;
    }

    public static int GetZoomShiftXDivZoomFactor()
    {
        return ZoomShiftXDivZoomFactor;
    }

    public static int GetZoomShiftY()
    {
        return ZoomShiftY;
    }

    public static int GetZoomShiftYDivZoomFactor()
    {
        return ZoomShiftYDivZoomFactor;
    }

    public static boolean IsZoomFactorFixedLarge(double ZoomFactor)
    {
        return (ZoomFactor == ZoomFactorFixedLarge);
    }

    public static boolean IsZoomFactorFixedSmall(double ZoomFactor)
    {
        return (ZoomFactor == ZoomFactorFixedSmall);
    }

    public static void SetDrawWidthAndHeight(int DrawWidthNew, int DrawHeightNew)
    {
        if (DrawWidthNew < 0 || DrawWidthNew > 1000000 || DrawHeightNew < 0 || DrawHeightNew > 1000000)
        {
            System.out.println("warning in ZoomManager.SetDrawWidthAndHeight(): passed value not useful!");
        }

        DrawWidth = DrawWidthNew;
        DrawHeight = DrawHeightNew;

        // precompute some stuff for speed reasons:

        ZoomShiftX = (int) (DrawWidth / 2 * (1 - ZoomFactor));
        ZoomShiftY = (int) (DrawHeight / 2 * (1 - ZoomFactor));

        DrawWidthMinusZoomShiftX = DrawWidth - ZoomShiftX;
        DrawHeightMinusZoomShiftY = DrawHeight - ZoomShiftY;

        ZoomShiftXDivZoomFactor = (int) (ZoomShiftX / ZoomFactor);
        ZoomShiftYDivZoomFactor = (int) (ZoomShiftY / ZoomFactor);

        DrawWidthMinusZoomShiftXDivZoomFactor = (int) (DrawWidthMinusZoomShiftX / ZoomFactor);
        DrawHeightMinusZoomShiftYDivZoomFactor = (int) (DrawHeightMinusZoomShiftY / ZoomFactor);

        NegZoomShiftXDivZoomFactor = -ZoomShiftXDivZoomFactor;
        NegZoomShiftYDivZoomFactor = -ZoomShiftYDivZoomFactor;
    }

    public static void SetZoomFactor(double ZoomFactorNew)
    {
        ZoomFactorNew = ((int) ((ZoomFactorNew + 0.005) * 100)) / 100.0; // round down to next lower 0.01-step; add some little amount against rounding errors (in tests, zoom never exceeded 0.35, sometimes...)

        if (ZoomFactorNew < 0.01)
            ZoomFactorNew = 0.01;
        if (ZoomFactorNew > 1.00)
            ZoomFactorNew = 1.00;

        ZoomFactorFixedUsed = false;
        ZoomFactor = ZoomFactorNew;
        ZoomFactorCustomLast = ZoomFactor;

        // IMPORTANT: we NEED to re-precompute all values which depend on ZoomFactor:
        SetDrawWidthAndHeight(DrawWidth, DrawHeight);
    }

    public static void SetZoomFactorFixedLarge()
    {
        if (!(ZoomFactorFixedUsed))
        {
            ZoomFactorCustomLast = ZoomFactor;
        }
        ZoomFactorFixedUsed = true;
        double ZoomFactorCustomLastUnchanged = ZoomFactorCustomLast;
        SetZoomFactor(ZoomFactorFixedLarge);
        ZoomFactorFixedUsed = true; // restore because SetZoomFactor() overwrote it
        ZoomFactorCustomLast = ZoomFactorCustomLastUnchanged; // restore because SetZoomFactor() overwrote it
    }

    public static void SetZoomFactorFixedSmall()
    {
        if (!(ZoomFactorFixedUsed))
        {
            ZoomFactorCustomLast = ZoomFactor;
        }
        ZoomFactorFixedUsed = true;
        double ZoomFactorCustomLastUnchanged = ZoomFactorCustomLast;
        SetZoomFactor(ZoomFactorFixedSmall);
        ZoomFactorFixedUsed = true; // restore because SetZoomFactor() overwrote it
        ZoomFactorCustomLast = ZoomFactorCustomLastUnchanged; // restore because SetZoomFactor() overwrote it
    }
}
